package com.atguigu.demojuc.chap02;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;


/**
 synchronized和ReentrantLock比较：

    1.都是具有可重入性的互斥锁
    2.synchronized加锁解锁无需我们管理(固定)；ReentrantLock加锁解锁必须程序员自己来管(灵活),加锁和解锁需要成对执行，否则容易死锁。
    3.synchronized加锁不可中断。ReentrantLock加锁可中断(tryLock())。
    4.synchronized只是一个互斥锁，不具有公平锁功能的。ReentrantLock可以选择非公平锁或公平锁使用。


 */


//解决死锁问题：限时等待  tryLock()
public class DeadlockDemo2 {
    public static void main(String[] args) {
        //ReentrantLock锁提供了限时等待（过时不候）功能。可以解决死锁问题。
        ReentrantLock lock1 = new ReentrantLock();
        ReentrantLock lock2 = new ReentrantLock();

        /*new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + "准备获取锁1");
            lock1.lock();
            System.out.println(Thread.currentThread().getName() + "\t" + "获得锁1=======准备获取锁2");
            lock2.lock();
            System.out.println(Thread.currentThread().getName() + "\t" + "获得锁2");
            lock2.unlock();
            lock1.unlock();
        }, "A").start();

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + "准备获取锁2");
            lock2.lock();
            System.out.println(Thread.currentThread().getName() + "\t" + "获得锁2=======准备获取锁1");
            lock1.lock();
            System.out.println(Thread.currentThread().getName() + "\t" + "获得锁1");
            lock1.unlock();
            lock2.unlock();
        }, "B").start();*/


        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + "准备获取锁1");
            try {
                boolean result = lock1.tryLock(1, TimeUnit.SECONDS);
                if (result) {
                    System.out.println(Thread.currentThread().getName() + "\t" + "获得锁1=============准备获得锁2");
                        boolean result1 = lock2.tryLock(10, TimeUnit.SECONDS);
                        if (result1) {
                            System.out.println(Thread.currentThread().getName() + "\t" + "获得锁2");
                            lock2.unlock();
                        }else {
                            System.out.println(Thread.currentThread().getName() + "\t" + "获取锁2失败");
                        }
                        lock1.unlock();
                }else {
                    System.out.println(Thread.currentThread().getName() + "\t" + "获取锁1失败");

                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t" + "准备获取锁2");
            try {
                boolean result = lock2.tryLock(1, TimeUnit.SECONDS);
                if (result) {
                    System.out.println(Thread.currentThread().getName() + "\t" + "获得锁2=============准备获得锁1");
                    boolean result1 = lock1.tryLock(1, TimeUnit.SECONDS);
                    if (result1) {
                        System.out.println(Thread.currentThread().getName() + "\t" + "获得锁1");
                        lock1.unlock();
                    }else {
                        System.out.println(Thread.currentThread().getName() + "\t" + "获取锁1失败");
                    }
                    lock2.unlock();
                }else {
                    System.out.println(Thread.currentThread().getName() + "\t" + "获取锁2失败");

                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, "B").start();
    }
}
